# include <stdio.h>
# include <stdlib.h>
# include <time.h>
# include <sys/types.h>
# include <pthread.h>
# include <semaphore.h>
# include <string.h>
# include <unistd.h>


// wrt(记录型信号量) 用于实现对文件的互斥访问
// mutex 用于对count变量的互斥访问
sem_t wrt, mutex;
//记录当前有几个读进程在访问文件
int readCount;


//读者
void* Reader(void* param) {
    while (1){
        // P操作，各进程互斥地访问 mutex
        sem_wait(&mutex);
        readCount++;
        if(readCount == 1)
            sem_wait(&wrt);
        //  V操作
        sem_post(&mutex);
        printf("Thread %d: is reading\n", pthread_self());
        sleep(3);
        sem_wait(&mutex);
        readCount--;
        if(readCount == 0)
            sem_post(&wrt);
        sem_post(&mutex);
    }
    //    结束进程
    pthread_exit(0);
}

//写者
void* Writer(void* param) {

    sem_wait(&wrt);
    printf("Thread %d: is writing\n", pthread_self());
    sleep(5);
    sem_post(&wrt);
    pthread_exit(0);
}

//获得线程属性
void getProperty(pthread_attr_t attr){
    int ret;
    //并发级别
    int level;
    ret = pthread_getconcurrency();
    if(0 != ret) {
        printf("error \n");
    } else {
        printf("线程并发级别为: %d\n", level);
    }
    //线程优先级
    int priority;
    ret = pthread_attr_getschedparam(&attr,&priority);
    if(0 != ret) {
        printf("error \n");
    } else {
        printf("线程优先级 : 优先级 %d\n", priority);
    }
    //线程的调度策略
    int policy;
    ret = pthread_attr_getschedpolicy(&attr, &policy);
    if(0 != ret) {
        printf("error\n");
    }
    else {
        if(SCHED_FIFO == policy)
            //先来先服务
            printf("线程调度策略: 先来先服务\n");
        else if(SCHED_RR == policy)
            //时间片轮转
            printf("线程调度策略: 时间片轮转\n");
        else if(SCHED_OTHER == policy)
            //其他
            printf("线程调度策略: 其他\n");
    }
    //线程栈大小
    size_t size;
    ret = pthread_attr_getstacksize(&attr, &size);
    if(0 != ret) {
        printf("error");
    } else {
        printf("线程栈大小: %lu\n", size);
    }
    //线程的作用域
    int scope;
    ret = pthread_attr_getscope(&attr, &scope);
    if(0 != ret) {
        printf("error");
    } else {
//        非绑定的
        if(PTHREAD_SCOPE_PROCESS == scope)
            printf("线程的作用域: PTHREAD_SCOPE_PROCESS\n");
        //绑定的线程  被绑定的线程具有较高的响应速度
        else if(PTHREAD_SCOPE_SYSTEM == scope)
            printf("线程的作用域: PTHREAD_SCOPE_SYSTEM\n");
    }
}
int main() {
    // 线程属性
    pthread_attr_t attr;
    //对线程属性进行初始化
    pthread_attr_init(&attr);
    //获取线程属性
    getProperty(attr);
    sem_init(&mutex, 0, 1);
    sem_init(&wrt, 0, 1);
    readCount = 0;
    pthread_t rid[10],wid[3];

    for (int i = 0; i < 3; ++i) {
        pthread_create(&wid[i], &attr, Writer, NULL);
    }
    for (int i = 0; i < 10; ++i) {
        pthread_create(&rid[i], &attr, Reader, NULL);
    }
    char c;
    if (scanf("%c",&c)=='q'){
        for (int i = 0; i < 10; ++i) {
            pthread_cancel(rid[i]);
        }
        for (int i = 0; i < 3; ++i) {
            pthread_cancel(wid[i]);
        }
    }
    //信号量销毁
    sem_destroy(&mutex);
    sem_destroy(&wrt);
    return 0;
}
